
const express = require('express');
const WebSocket = require('ws');
const protobuf = require('protobufjs');
const path = require('path');
const fs = require('fs');

// 初始化Express应用
const app = express();
const PORT = process.env.PORT || 3000;

// 加载所有Protobuf协议文件
const protoFiles = {
    chat: loadProtoFile('chat.proto'),
    file: loadProtoFile('file.proto'),
    notification: loadProtoFile('notification.proto')
};

// 消息类型枚举
const MessageType = {
    CHAT: 1,
    FILE: 2,
    NOTIFICATION: 3
};

// HTTP路由
app.use(express.static('public'));
app.get('/status', (req, res) => {
    res.json({ status: 'running', timestamp: Date.now() });
});

// 创建HTTP服务器
const server = app.listen(PORT, () => {
    console.log(`Server started on port ${PORT}`);
});

// WebSocket服务器
const wss = new WebSocket.Server({ server });

wss.on('connection', (ws) => {
    console.log('New client connected');

    ws.on('message', (message) => {
        handleWebSocketMessage(ws, message);
    });

    ws.on('close', () => {
        console.log('Client disconnected');
    });
});

// 消息处理函数
function handleWebSocketMessage(ws, message) {
    try {
        const messageType = message.readUInt8(0);
        const payload = message.slice(1);

        switch (messageType) {
            case MessageType.CHAT:
                const chatMsg = decodeMessage('chat', 'ChatMessage', payload);
                broadcastChatMessage(chatMsg);
                break;

            case MessageType.FILE:
                const fileMeta = decodeMessage('file', 'FileMeta', payload);
                processFileUpload(fileMeta);
                break;

            case MessageType.NOTIFICATION:
                const notification = decodeMessage('notification', 'Notification', payload);
                sendNotification(notification);
                break;

            default:
                ws.send(createErrorResponse('Unknown message type'));
        }
    } catch (err) {
        console.error('Message processing error:', err);
        ws.send(createErrorResponse(err.message));
    }
}

// 辅助函数
function loadProtoFile(filename) {
    const protoPath = path.join(__dirname, 'proto', filename);
    return protobuf.loadSync(protoPath);
}

function decodeMessage(protoKey, messageType, buffer) {
    const root = protoFiles[protoKey];
    const Message = root.lookupType(messageType);
    return Message.decode(new Uint8Array(buffer));
}

function broadcastChatMessage(message) {
    const buffer = createMessageBuffer(MessageType.CHAT, 'chat', 'ChatMessage', message);
    wss.clients.forEach(client => {
        if (client.readyState === WebSocket.OPEN) {
            client.send(buffer);
        }
    });
}

function createMessageBuffer(type, protoKey, messageType, payload) {
    const typeBuffer = Buffer.from([type]);
    const message = protoFiles[protoKey].lookupType(messageType).create(payload);
    const payloadBuffer = Buffer.from(protoFiles[protoKey].lookupType(messageType).encode(message).finish());
    return Buffer.concat([typeBuffer, payloadBuffer]);
}

function createErrorResponse(message) {
    return JSON.stringify({ error: true, message });
}
